<?php

namespace App\Jobs;

use App\Models\MessagesSentFailure;
use App\Models\MessagesSentSucceed;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Redis;
use App\Models\MessagesSent;

class SnsQueue implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $params;
    protected $remark;
    protected $send_succ = 0;
    protected $send_fail = 0;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($params)
    {
        $this->params = $params;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $action = $this->params['action'];
        $params_data = $this->params['data'];
        switch ($params_data['msg_type']){
            case 0:
                $this->remark = '推广短信发送';
                break;
            case 1:
                $this->remark = '通讯录绑定，短信发送';
                break;
        }
        $data = $this->$action($params_data);
    }

    /*
     * 累加推送
     * 按配置400条批次发送
     * */
    private function accumulation_send($params_data)
    {
        $content = $params_data['content'];
        $msg_id = $params_data['msg_id'];
        $type = $params_data['msg_type'];
        $sns_key = 'sns:'.$msg_id.':'.$type;

        //每400条一个批次
        $count = Redis::zcard($sns_key);
        $end_pagesize = config('basic.xs_sns.xs_sns_batch_num');//$count%$pagesize+$pagesize;
        $total_page = (int)ceil($count/$end_pagesize);

        for($ii=0;$ii<$total_page;$ii++){
            // 取出第一页  -- 发送短信
            $list = Redis::zrange($sns_key, 0, ($end_pagesize-1));

            // 未满足一个批次
            if(empty($list) || count($list) < $end_pagesize)
                return false;

            $mobile_str = implode(',', $list);
            $send_message = true;
            if(config('basic.xs_sns.xs_sns_debug') != true){
                $send_message = send_group_msg($mobile_str, $content);
            }

            // 删除成功  -- 删除
            if($send_message == true) {
                $del = Redis::zrem($sns_key, $list);

                $batch_mobile = [];
                foreach($list as $mobile)
                    $batch_mobile[] = ['msg_id' => $msg_id, 'msg_type' => $type, 'mobile' => $mobile, 'created_at' => time(), 'remark' => $this->remark.'发送成功'];
                if(!empty($batch_mobile))
                    MessagesSentSucceed::insert($batch_mobile);
            }else{

                $sns_send_error_data = Redis::get('GroupSms:'.md5($mobile_str));
                $failure_mobile_list = [];
                foreach($list as $mobile)
                    $failure_mobile_list[] = ['msg_id' => $msg_id, 'msg_type' => $type, 'mobile' => $mobile, 'created_at' => time(), 'remark' => $this->remark.'发送失败！'.$sns_send_error_data];
                if(!empty($failure_mobile_list))
                    $dd  = MessagesSentFailure::insert($failure_mobile_list);
            }
        }
    }

    /**
     * @desc 群发短信发送
     * @param $params_data
     * @return array|bool
     */
    private function group_sms_send($params_data)
    {
        $msg_id = $params_data['msg_id'];
        if(empty($msg_id)) {
            return false;
        }

        // 判断消息配置是否满足条件发送
        $fields = ['id', 'content', 'user_type', 'status', 'send_succ'];
        $messages_info = MessagesSent::where(['id' => $msg_id])->first($fields);
        if(empty($messages_info)) {
            return false;
        }
        if($messages_info->status != 1) {
            return true; // 该队列已处理完
        }

        $rs = MessagesSent::where(['id' => $msg_id, 'status' => 1])->update(['status' => 2]);
        if(!$rs) {
            return false;
        }

        $page_size = config('basic.xs_sns.xs_sns_batch_num');
        $wait_send_mobile_key = 'GroupSms:send_group_sms_mobile_'.$msg_id;
        $total = Redis::zcard($wait_send_mobile_key);
        $total_page = (int)ceil($total / $page_size);
        for($i=0;$i<$total_page; $i++) {
            $mobile_list = Redis::zrange($wait_send_mobile_key, 0, ($page_size-1));
            $this->_sent_messages($mobile_list, $msg_id, $messages_info->content);
            if(!empty($mobile_list)) {
                Redis::zrem($wait_send_mobile_key, $mobile_list);   // 删除已处理的手机号
            }
        }

        // 标记任务结束
        $data = [
            'status' => 3,
            'send_succ' => $this->send_succ + $messages_info->send_succ,
            'send_fail' => $this->send_fail
        ];
        MessagesSent::where(['id' => $msg_id, 'status' => 2])->update($data);

        return true;
    }

    protected function _sent_messages($mobile_list, $msg_id, $content)
    {
        if(empty($mobile_list)) {
            return true;
        }

        if(count($mobile_list) < 100) {
            return true;
        }

        if(stripos($content, '【i微影】') !== 0) {
            $content = '【i微影】'.$content;
        }
        $send_list = implode(',', $mobile_list);
        $send_rs = true;
        if(config('basic.xs_sns.xs_sns_debug') != true){
            $send_rs = send_group_msg($send_list, $content);
        }
        if(!$send_rs) {
            $failure_mobile_list = [];
            $error_messages = Redis::get('GroupSms:'.md5($send_list));
            foreach($mobile_list as $mobile) {
                $failure_mobile_list[] = ['msg_id' => $msg_id, 'msg_type' => 0, 'mobile' => $mobile, 'created_at' => time(), 'remark' => $this->remark.'失败，失败原因：'.$error_messages];
            }
            if(!empty($failure_mobile_list)) {
                MessagesSentFailure::insert($failure_mobile_list);
            }
            $this->send_fail += count($mobile_list);
            return false;
        }

        // 发送成功的手机号码保存到表
        $batch_mobile = [];
        foreach($mobile_list as $mobile) {
            $batch_mobile[] = ['msg_id' => $msg_id, 'msg_type' => 0, 'mobile' => $mobile, 'created_at' => time(), 'remark' => $this->remark.'成功'];
        }

        if(!empty($batch_mobile)) {
            MessagesSentSucceed::insert($batch_mobile);
        }

        $this->send_succ += count($mobile_list);
        return true;
    }

}
